﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
using GalaSoft.MvvmLight.Messaging;
using Northwind.ViewModel.Messeges;
using Northwind.Interfaces.Data.Model;
using GalaSoft.MvvmLight.Command;
using Northwind.Application;

namespace Northwind.ViewModel
{
    public class MainWindowViewModel : NamedViewModel
    {
        #region Properties

        private ControlPanelViewModel _controlPanel;

        public ControlPanelViewModel ControlPanel
        {
            get
            {
                if (_controlPanel == null)
                {
                    _controlPanel 
                        = new ControlPanelViewModel();
                    _controlPanel.ShowCustomerDetails 
                        += ControlPanelShowCustomerDetails;
                }
                return _controlPanel;
            }
        }

        private ObservableCollection<ToolViewModel> _tools;
        public ObservableCollection<ToolViewModel> Tools
        {
            get
            {
                if (_tools == null)
                {
                    _tools = new ObservableCollection<ToolViewModel>();
                    _tools.CollectionChanged += OnToolsCollectionChanged;
                }
                return _tools;
            }
        }

        #endregion Properties

        #region Commands

        RelayCommand _showOrderWizard;
        public RelayCommand ShowOrderWizard
        {
            get
            {
                if (_showOrderWizard == null)
                {
                    _showOrderWizard = new RelayCommand(
                        () => { IsShowOrderWizard = true; });
                }
                return _showOrderWizard;
            }
        }

        bool _isShowOrderWizard = false;
        public bool IsShowOrderWizard
        {
            get { return _isShowOrderWizard; }
            set 
            {
                _isShowOrderWizard = value;
                RaisePropertyChanged("IsShowOrderWizard");
                
            }
        }

        #endregion

        #region ctor

        public MainWindowViewModel()
            : base(Strings.MainWindowDisplayName)
        {
            Initialize();
            
        }

        private void Initialize()
        {
            SubscribeMessages();

            
        }

        #endregion ctor

        #region Command handlers

        void ControlPanelShowCustomerDetails(object sender,
        CustomerEventArgs e)
        {
            CustomerDetailsViewModel customerDetailsViewModel
                = Tools.Where<ToolViewModel>((toolViewModel) => toolViewModel.GetType() == typeof(CustomerDetailsViewModel)).Cast<CustomerDetailsViewModel>()
                      .FirstOrDefault(
                          detailsViewModel =>
                          detailsViewModel.Customer.CustomerID == e.CustomerID
                      ) ?? GetNewCustomerDetailsViewModel(e.CustomerID);
            SetCurrentTool(customerDetailsViewModel);
        }



        #endregion Command handlers

        #region Event handlers

        void OnToolsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null && e.NewItems.Count != 0)
                foreach (ToolViewModel tool in e.NewItems)
                    tool.RequestClose += OnToolRequestClose;

            if (e.OldItems != null && e.OldItems.Count != 0)
                foreach (ToolViewModel tool in e.OldItems)
                    tool.RequestClose -= OnToolRequestClose;
        }

        void OnToolRequestClose(object sender, EventArgs e)
        {
            ToolViewModel tool = sender as ToolViewModel;
            Tools.Remove(tool);            
            tool.Dispose();
        }

        #endregion Event handlers

        #region Helpers

        private void SetCurrentTool(ToolViewModel currentTool)
        {
            ICollectionView collectionView = CollectionViewSource.GetDefaultView(Tools);
            if (collectionView != null)
            {
                if (collectionView.MoveCurrentTo(currentTool) != true)
                {
                    throw new InvalidOperationException("Could not find the current tool.");
                }
            }
        }

        private void SubscribeMessages()
        {
            Messenger.Default.Register<ShowOrder>(this, ShowOrder);
            
            Messenger.Default.Register<OrderWizardClosed>(this, (a) =>
                {
                    this.IsShowOrderWizard = false;
                });

            Messenger.Default.Register<ShowNewOrderWizard>(this, ShowNewOrderWizard);

        }

        private void ShowNewOrderWizard(ShowNewOrderWizard showNewOrderWizard)
        {
            IsShowOrderWizard = true;
        }

        private void ShowOrder(ShowOrder showOrderMessage)
        {
            IOrderModel orderViewModel
                 = Core.Instance.NorthwindManager.GetOrder(showOrderMessage.OrderID);

            OrderDetailsViewModel orderDetailsViewModel
                = Tools.Where<ToolViewModel>(
                    (toolViewModel) =>
                        toolViewModel.GetType() == typeof(OrderDetailsViewModel)).Cast<OrderDetailsViewModel>()
                      .FirstOrDefault(
                          detailsViewModel =>
                          detailsViewModel.Order.OrderID == orderViewModel.OrderID
                      ) ?? GetOrderDetailsToolToDisplay(orderViewModel);

            SetCurrentTool(orderDetailsViewModel);
        }

        private CustomerDetailsViewModel GetNewCustomerDetailsViewModel(string customerID)
        {
            CustomerDetailsViewModel customerDetailsViewModel
                = new CustomerDetailsViewModel(customerID);
            Tools.Add(customerDetailsViewModel);
            return customerDetailsViewModel;
        }

        private OrderDetailsViewModel GetOrderDetailsToolToDisplay(IOrderModel orderViewModel)
        {
            OrderDetailsViewModel orderDetailsViewModel = new OrderDetailsViewModel(orderViewModel);
            Tools.Add(orderDetailsViewModel);

            return orderDetailsViewModel;
        }

        #endregion Helpers
    }
}